package chances.system.operator.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import chances.system.operator.entity.Menu;
import chances.system.operator.entity.Operator;
import chances.system.operator.entity.Oplog;
import chances.system.operator.entity.Permission;
import chances.system.operator.entity.Role;
import chances.system.operator.repo.MenuRepository;
import chances.system.operator.repo.OperatorRepository;
import chances.system.operator.repo.OplogRepository;
import chances.system.operator.repo.OrganizationRepository;
import chances.system.operator.repo.PermissionRepository;
import chances.system.operator.web.OperatorSession;
import chances.webui.model.Tree;
import chances.webui.model.TreeNode;

@Service
public class OperatorService implements UserDetailsService{
	@Autowired
	OperatorRepository operatorRepository;
	
	@Autowired
	OrganizationRepository organizationRepository;

	@Autowired
	MenuRepository menuRepository;

	@Autowired
	PermissionRepository permissionRepository;
	
	
	@Autowired
	OplogRepository oplogRepository;
	
	public List<Permission> listOperatorMenuPermssions(Operator operator) {
		Set<Long> ids = operator.getRoles().stream().map(Role::getId).collect(Collectors.toSet());
		return this.permissionRepository.findByResTypeAndObjTypeAndObjIdIn("menu", "role", ids);
	}
	
	
	public OperatorSession createUserSession(Operator user) {
		return new OperatorSession(user,createOperatorMenu(user));
	}
	
	public Tree<Menu> createOperatorMenu(Operator operator) {
		List<Permission> perms = listOperatorMenuPermssions(operator);
		List<Long> menuIds = perms.stream().map(Permission::getResId).collect(Collectors.toList());
		List<Menu> saveMenus = menuRepository.findByMenuIdIn(menuIds);
		List<Menu> avaliableMenus = menuRepository.findAvaliableMenu();
		List<Menu> resMenus = new ArrayList<>();
		for (Menu saveMenu : saveMenus) {
			for (Menu avaliableMenu : avaliableMenus) {
				if(!resMenus.contains(avaliableMenu) && (
						avaliableMenu.getLocation().startsWith(saveMenu.getLocation())
						|| saveMenu.getLocation().startsWith(avaliableMenu.getLocation())))
					resMenus.add(avaliableMenu);
			}
		}
		List<TreeNode<Menu>> nodes = resMenus.stream().map(s -> {
			return createMenuNode(s);
		}).collect(Collectors.toList());
		Tree<Menu> menuTree = new Tree<Menu>(nodes);
		return menuTree;
	}
	
	
	public TreeNode<Menu> createMenuNode(Menu item) {
		TreeNode<Menu> node = new TreeNode<Menu>();
		node.setEntry(item);
		node.setTitle(item.getTitle());
		node.setPath(item.getLocation());
		node.setId(item.getMenuId().toString());
		node.setLink(item.getHref());
		node.setParentId(item.getParentId().toString());
		return node;
	}


	public Operator getByLoginName(String username) {
		return operatorRepository.getByLoginName(username);
	}


	public void save(Oplog oplog) {
		oplogRepository.save(oplog);
		
	}
	
	public void save(List<Oplog> oplogs) {
		oplogRepository.save(oplogs);
	}

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<Operator> operators = operatorRepository.findByLoginName(username);
        if (null == operators || operators.size()<=0) {
            throw new UsernameNotFoundException("登录帐号不存在，请重新输入");
        }
        if (!operators.get(0).isEnabled()) {
            throw new DisabledException("用户已被禁用,请联系系统管理员");
        }
		OperatorSession operatorSession = this.createUserSession(operators.get(0));
        return operatorSession;
	}
}
